﻿using OnlineEducation.Constants;
using OnlineEducation.Data;
using OnlineEducation.Helpers;
using OnlineEducation.Models.ServerAPIModels;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace OnlineEducation.Job
{
    internal class UpdateStatusTaskHostedService : IHostedService, IDisposable
    {
        private static object lockObj = new object();//定义锁

        private readonly IServiceScopeFactory scopeFactory;

        private readonly ILogger _logger;
        private ApplicationDbContext _context;
        private Timer _timer;
        private readonly IWebHostEnvironment _hostingEnv;

        private readonly string Job_Name = "UpdateStatusTask-";

        public UpdateStatusTaskHostedService(IServiceScopeFactory scopeFactory,
            ILogger<UpdateStatusTaskHostedService> logger,
            IWebHostEnvironment hostingEnv)
        {
            this.scopeFactory = scopeFactory;
            _logger = logger;
            _hostingEnv = hostingEnv;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
           // _logger.LogInformation($"[{DateTime.Now:yyyy-MM-dd hh:mm:ss}]{Job_Name}background service is starting.");

            _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));

            return Task.CompletedTask;
        }

        private void DoWork(object state)
        {
            lock (lockObj)
            {
                using (var scope = scopeFactory.CreateScope())
                {
                    _context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

                    #region  
                    try
                    {
                        var plans = _context.TeachingPlans.Include(n => n.TeachingPlanItems).Where(n => n.Status == 1 ).ToList();

                        foreach (var plan in plans)
                        {
                            if (plan.TeachingPlanItems.All(n => n.Status == 2))
                            {
                                plan.Status = 2;

                                _context.Update(plan);

                                _logger.LogInformation($"{Job_Name}Update teaching plan {plan.Id} status as done successfully.");
                            }
                          
                        }

                        _context.SaveChanges();


                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex.Message, ex.ToString());

                    }
                    #endregion

                }
            }
        }


        public Task StopAsync(CancellationToken cancellationToken)
        {
            //_logger.LogInformation($"[{ DateTime.Now:yyyy-MM-dd hh:mm:ss}]{Job_Name}background service is stopping.");

            _timer?.Change(Timeout.Infinite, 0);

            return Task.CompletedTask;
        }

        public void Dispose()
        {
            _timer?.Dispose();
        }
    }



}
